package com.huatech.core.amqp;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.huatech.core.domain.User;
/**
 * 参考配置：
 * 1、application.properties
 *  #开启 confirm 确认机制
	spring.rabbitmq.publisher-confirms=true
	#开启 return 确认机制
	spring.rabbitmq.publisher-returns=true
	#设置为 true 后 消费者在消息没有被路由到合适队列情况下会被return监听，而不会自动删除
	spring.rabbitmq.template.mandatory=true
	
 * 
 */
@Component
public class UserConfirmProducer implements RabbitTemplate.ReturnCallback, RabbitTemplate.ConfirmCallback{

	private static final Logger LOGGER = LoggerFactory.getLogger(UserConfirmProducer.class);
	@Autowired
	private RabbitTemplate rabbitTemplate;

	@PostConstruct
	private void init() {
		// 消息发送到交换器时触发
		rabbitTemplate.setConfirmCallback(this);
		// 消息从交换器发送到队列失败时触发
		rabbitTemplate.setReturnCallback(this);
		rabbitTemplate.setMandatory(true);
	}

	public void send(User user) {
		LOGGER.info("Sender : {}", user.toString());
		CorrelationData cd = new CorrelationData(user.getUuid());
		rabbitTemplate.convertAndSend(RabbitConstant.EXCHANGE_DIRECT, RabbitConstant.QUEUE_USER, user, cd);
	}

	@Override
	public void confirm(CorrelationData correlationData, boolean ack, String cause) {
		System.out.println("id:" + correlationData.getId() + ", msg:" + correlationData.getReturnedMessage());
		LOGGER.info("correlationData: {}, ack:{}, cause:{}", correlationData, ack, cause);
		if (!ack) {
			// TODO:将消息放入缓存，网络异常时重新调用send方法
			LOGGER.info("异常处理....");
		} else {
			LOGGER.info("正常处理....");
		}
	}

	@Override
	public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
		LOGGER.info("returnCallback exchange:{}, routingKey:{}, replyCode:{},  replyText: ", exchange, routingKey,
				replyCode, replyText);
	}

}
